﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Text.RegularExpressions;
using Graffiti.Core;

namespace GraffitiExtras.Extensions.SearchRelevancy
{
    [Chalk("searchRelevancy")]
    public class SearchRelevancy
    {
        #region Public methods

        public string GetRelevantPosts(int count, string pattern)
        {
            string referrerUrl = string.Empty;

            try
            {
                HttpContext context = HttpContext.Current;
                referrerUrl = context.Request.UrlReferrer.ToString();
            }
            catch
            {
                // Do nothing!
            }

            if (!string.IsNullOrEmpty(referrerUrl))
            {
                try
                {
                    string keywords = GetKeywords(referrerUrl);

                    if (!string.IsNullOrEmpty(keywords))
                    {
                        SearchResultSet<Post> tempPosts = GetRelevantItems(keywords, count);

                        SearchResultSet<Post> posts = new SearchResultSet<Post>();

                        Macros macros = new Macros();

                        foreach (Post post in tempPosts)
                        {
                            if (HttpContext.Current != null)
                            {
                                string fullUrl = macros.FullUrl(post.Url);
                                string curUrl = HttpContext.Current.Request.Url.ToString();
                                if (curUrl.Contains("Default.aspx"))
                                {
                                    curUrl = curUrl.Replace("Default.aspx", "");
                                }
                                if (fullUrl != curUrl)
                                {
                                    posts.Add(post);
                                }
                            }
                            else
                            {
                                posts.Add(post);
                            }
                        }

                        if ((posts != null) && (posts.Count > 0))
                            return GetHtmlCode(pattern, keywords, posts);
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("Search Relevancy Extension", ex.Message + ex.StackTrace);
                }
            }

            return string.Empty;
        }

        #endregion

        #region Private methods

        private string GetKeywords(string referrerUrl)
        {
            List<string> patterns = new List<string>();
            patterns.Add("search");

            foreach (string pattern in patterns)
            {
                if (Regex.IsMatch(referrerUrl, pattern))
                {
                    List<string> queryPatterns = new List<string>();
                    queryPatterns.Add(@"q=([\w\.\+\-\%]+)");
                    queryPatterns.Add(@"q=([\w\.\+\-\%]+)&");

                    foreach (string queryPattern in queryPatterns)
                    {
                        Regex regEx = new Regex(queryPattern, RegexOptions.IgnoreCase);

                        Match match = regEx.Match(referrerUrl);

                        if (!string.IsNullOrEmpty(match.Value))
                            return HttpContext.Current.Server.UrlDecode(match.Groups[1].Value);
                    }
                }
            }
            return null;
        }

        private SearchResultSet<Post> GetRelevantItems(string keywords, int count)
        {
            try
            {
                SearchQuery query = new SearchQuery();
                query.QueryText = keywords;
                query.Sort = SearchSort.Relevance | SearchSort.Descending;
                query.PageSize = count;
                query.PageIndex = 0;

                SearchIndex index = new SearchIndex();

                return index.Search(query);
            }
            catch (Exception ex)
            {
                Log.Error("Search Relevancy Extension", ex.Message + ex.StackTrace);
            }
            return null;
        }

        private string GetHtmlCode(string pattern, string keywords, SearchResultSet<Post> posts)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("<div id=\"SearchRelevancy\"><p>" + pattern + "<ul>", keywords);

            foreach (Post post in posts)
            {
                sb.AppendFormat("<li><a href=\"{0}\">{1}</a></li>",
                    new Macros().FullUrl(post.Url), post.Title);
            }

            sb.Append("</ul></p></div>");
            return sb.ToString();
        }

        #endregion
    }
}
